package com.hcss.common.util;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.poi.ss.formula.functions.T;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.hcss.common.constant.CommonConstants;

/**
 * @function : 集合工具
 */
@SuppressWarnings("unchecked")
public class ListUtil {
	
	/**
	 * set转list
	 * @param list
	 * @return
	 */
	public static<T> List<T> set2List(Set<T> list){
		if(list == null || list.isEmpty()){
			return null;
		}
		
		return new ArrayList<T>(list);
	}
	
	/**
	 * list转换成set集合
	 * @param list
	 * @return
	 */
	public static<T> Set<T> list2Set(List<T> list){
		if(EmptyUtil.isEmpty(list)){
			return null;
		}
		
		return new HashSet<T>(list);
	}
	
	/**
	 * 合并集合成为一个字符串
	 * @param list
	 * @param split
	 * @return
	 */
	public static<T> String splice(Collection<T> list, String split){
		if(EmptyUtil.isEmpty(list)){
			return null;
		}
		split = EmptyUtil.isHaveEmpty(split) ? "" : split;
		
		StringBuffer result = new StringBuffer();
		for(T one : list){
			if(EmptyUtil.isHaveEmpty(one)){
				continue;
			}
			result.append( one+ split);
		}
		return result.substring(0, result.length() - split.length());
	}
	
	/**
	 * 根据属性值，在集合里面找到一个符合的数据
	 * @param list
	 * @param attrName
	 * @param value
	 * @return
	 * @throws Exception
	 */
	public static<T> T findByAttrValue(Collection<T> list, String attrName, Object value) throws Exception{
		if(EmptyUtil.isEmpty(list) || EmptyUtil.isHaveEmpty(attrName, value)){
			return null;
		}
		for(T one : list){
			Object oneValue = ReflectUtil.getValue(one, attrName);
			if(value.equals(oneValue)){
				return one;
			}
		}
		
		return null;
	}
	
	/**
	 * 将两个集合合并
	 * @param first
	 * @param second
	 * @return
	 */
	public static<T> List<T> combine(List<T> first, List<T> second){
		if(EmptyUtil.isEmpty(first)){
			return second;
		}
		
		if(EmptyUtil.isEmpty(second)){
			return first;
		}
		
		first.addAll(second);
		return first;
	}
	
	/**
	 * 取俩个集合交集
	 * @param first
	 * @param second
	 * @return
	 */
	public static<T> List<T> intersect(List<T> first, List<T> second){
		if(EmptyUtil.isEmpty(first)){
			return null;
		}
		
		if(EmptyUtil.isEmpty(second)){
			return null;
		}
		first.retainAll(second);
		return first;
	}
	
	/**
	 * 从source集合中剔除from集合
	 * @param source
	 * @param from
	 * @return
	 */
	public static<T> List<T> removeAll(List<T> source, List<T> from){
		if (EmptyUtil.isEmpty(source) || EmptyUtil.isEmpty(from)){
			return source;
		}
		source.removeAll(from);
		return source;
	}
	
	/**
	 * 想对象集合的对象的某一个属性进行批量设置值
	 * @param list
	 * @param attrName
	 * @param value
	 * @throws Exception
	 */
	public static void setAttrList(Collection<?> list, String attrName, Object value) throws Exception{
		if(EmptyUtil.isEmpty(list)){
			return;
		}
		for(Object one : list){
			ReflectUtil.setValue(one, attrName, value);
		}
	}
	
	/**
	 * 将对象集合的对象的某一个属性转换成一个属性值集合
	 * @param list
	 * @param attrName
	 * @return
	 * @throws Exception
	 */
	public static<T> List<T> getAttrList(List<?> list, String attrName)  throws Exception{
		if(EmptyUtil.isEmpty(list)){
			return null;
		}
		
		List<T> result = new ArrayList<T>();
		for(Object one : list){
			result.add((T) ReflectUtil.getValue(one, attrName));
		}
		
		return result;
	}

    /**
     * 将对象集合的对象的某一个属性转换成一个属性值","连接后返回
     * @param list
     * @param attrName
     * @return
     * @throws Exception
     */
	public static String getAttrString(List<?> list, String attrName)  throws Exception{
	    List<T> data = getAttrList(list, attrName);
	    return splice(data, CommonConstants.COMMA);
    }
	
	/**
	 * 获取first和second相同的内容
	 * @param first
	 * @param second
	 * @return
	 */
	public static<T, D extends Collection<T>> D retain(D first, D second){
		if(EmptyUtil.isEmpty(second) || EmptyUtil.isEmpty(first)){
			return first;
		}
		
		first.retainAll(second);
		return first;
	}
	
	/**
	 * 将字符串集合转换成指定类型集合
	 * @param list
	 * @param claz
	 * @return
	 * @throws Exception
	 */
	public static<T> List<T> convey(List<String> list, Class<T> claz) throws Exception{
		List<T> result = new ArrayList<T>();
		if(EmptyUtil.isHaveEmpty(claz) || EmptyUtil.isEmpty(list)){
			return result;
		}else if(claz.equals(String.class)){
			return (List<T>) list;
		}
		
		Constructor<T> constructor = claz.getConstructor(String.class);
		for(String one : list){
			result.add( constructor.newInstance(one) );
		}
		return result;
	}

    /**
     * 将json数组对象转换成指定list对象
     * @param obj_str
     * @param claz
     * @param <T>
     * @return
     * @throws Exception
     */
	public static<T> List<T> convey(String obj_str, Class<T> claz) throws Exception{
		if(EmptyUtil.isHaveEmpty(claz, obj_str)){
			return null;
		}

        JSONArray array = JSON.parseArray(obj_str);
        List<T> result = new ArrayList<T>(array.size());
        for(int i = 0; i < array.size(); i++){
			result.add(array.getObject(i, claz));
		}
		return result;
	}

	/**
	 * 分割字符串
	 * @param str
	 * @param split
	 * @return
	 */
	public static List<String> split(String str, String split){
		List<String> result = new ArrayList<String>();
		if(EmptyUtil.isHaveEmpty(str, split)){
			result.add(str);
			return result;
		}
		String[] strs = str.split(split);
		for(String one : strs){
			if(!EmptyUtil.isHaveEmpty(one)){
				result.add(one);
			}
		}
		return result;
	}
	
	/**
	 * 将集合中的每一个字符串都分割
	 * @param list
	 * @param separator
	 * @return
	 */
	public static List<List<String>> split(List<String> list, String separator){
		List<List<String>> result = new ArrayList<List<String>>();
		if(EmptyUtil.isEmpty(list)){
			return result;
		}
		Iterator<String> iterator = list.iterator();
		while(iterator.hasNext()){
			result.add(split(iterator.next(), separator));
		}
		return result;
	}
	
	public static void showOneByOne(Collection<?> list){
		if(EmptyUtil.isEmpty(list)){
			return;
		}
		
		Iterator<?> iterators = list.iterator();
		for(;iterators.hasNext();){
			System.out.println(iterators.next());
		}
	}

	public static<T> Map<Integer, List<T>> convertListToMap(List<T> list, String attrName) throws Exception{
        Map<Integer, List<T>> map = new HashMap<>(list.size());
        List<T> temp;
        for(T one : list){
            Integer attrValue = (Integer) ReflectUtil.getValue(one, attrName);
            if (map.containsKey(attrValue)) {
                map.get(attrValue).add(one);
            } else {
                temp = new ArrayList<>();
                temp.add(one);
                map.put(attrValue, temp);
            }
        }
        return map;
    }
}
